Welcome back.
We're nearly complete with our game.
The only thing left for us to do is script the system that will be responsible for handling any developer
product purchases in our game.
If you don't know what a developer product is, it's basically the same thing as a Game Pass, but they
can be purchased multiple times like revives, in-game currency and stuff like that.
So we want to give our players the ability to respawn into the map after they die by purchasing a cheap
developer product, maybe like 20 Robux so they can have another shop of escaping and winning the game.
To do this, we have a button inside of our GUI inside of the spectating frame that the players can
press to respawn, and when they press this button, what we could do is we could fire an event to the
server to request for a respawn, and which the server will prompt for us to purchase a developer product.
And when we purchase that developer product, the server will handle the rest of the functionality for
that specific developer product.
So in our case, when a player hits this respawn button, we want to prompt them to purchase a developer
product.
And when they purchase that developer product, we can basically respawn their character by selecting
one of these different respawn points that we have in the basement, and we can calculate which one
for the player to respawn at by determining which respawn point is farthest away from our AI.
Squidward.
Because we don't want to respawn the player directly on our AI and have them die immediately, that
wouldn't really be fair.
So we're going to use this response system and check which respawn point is best for our players to
respawn at, and we'll give them their tools back, like a flashlight and a glow stick and things like
that to give them another shot at trying to escape the basement.
So let me go ahead and disable the visibility on our spectate frame.
And in order to do this, we're going to have to create a new developer product.
So we can do that by going to file hitting game settings and going to the monetization tab.
And inside of here we have a section to create a developer product.
So we can hit this.
And as you can see we have a new developer product here.
And we can go ahead and edit this developer product.
And I'm going to give this name respawn.
But you can name it whatever you like.
And you can go ahead and set a price for this one.
We could do something like 20 Robux and then you can hit save.
And then from this point we can go back to game settings, go back to monetization, and here's our
developer product.
And we can go ahead and copy this ID because we're going to need it for later.
And then we can go ahead and close out of this.
So what the plan is, is that inside of our main UI handler, inside of our spectate frame, when we
hit that respawn button, we would want to use our game comms event to fire to the server to request
a respawn.
So remember inside of our game comms enum, in the two server section, we have an action of requesting
a respawn so we can fire this action to the server, and the server will determine what to do when we
give them this action.
So you can go ahead and open up your developer products, service and product ID enum inside of server
Script service and inside of here we're going to need several services.
One is going to be Replicated storage.
We're also going to need server storage.
We're going to need the team service.
And we're also going to need the marketplace service.
So game get service marketplace service.
And lastly we're going to need the player service.
Now inside of our product id enum.
This is where we're going to store all of the possible different developer product IDs.
So I'm just going to paste my ID in there real quick.
And from this point I'm just going to go into something like replicated storage and copy one of these
enums, just copy all this stuff in here, and then I could just paste it in here.
And what I'll do is I'll re copy my ID.
And delete all the stuff in here, and I'll just create a new key value pair for my respawn ID, so
I can call this respawn.
And all it's going to be equal to is our developer product ID, just like that.
Then we can go back to our developer product service.
We can go ahead and create the table to represent the service.
So we can call it product service.
We go to a table and we'll make sure to return this at the end of our script.
And then we're also going to go ahead and get our product ID numb.
So we'll require from our script dot product id num.
And we're going to have to also get our game comms event, which is in replicated storage, dot events,
dot remotes, dot game communication.
And then we're going to have to get our game comms enum require replicated storage, dot modules dot
enums, dot game communication.
We're also going to make a reference to our AI, Squidward, because we're going to need him for when
we need to respawn a player, because we need to tell which respawn point is farthest away from our
AI.
Squidward.
So we'll just make a reference to him and he's inside of server storage.
Other stuff.
Handsome Squidward.
I.
And they're also going to get all the different respawn points that are inside of our basement.
And that's in the workspace filtering folder.
Respawn points.
And there's the basement respawn points.
And we're going to get all of the children inside of there.
Another thing we're going to want to make sure of is to have a cool down for our event.
So we don't want a player to keep spam clicking that respawn event, and we don't want to keep constantly
prompting a purchase to the player so we can create a table.
I'll call it prompt cooldown.
Or cooldowns, prompt cooldowns, and this will just keep track of when the player last fired that event.
So we don't, you know, spam them with a prompt purchase every few seconds so we can create a constant.
And we can call it prompt cool down and we could do something like five seconds.
From this point, we can go ahead and create the initialize function for our product service.
In it.
And this is going to listen to our Game Comms event on server event.
And we can connect a private function to it.
So we could create a function.
We could call it on game Comms event.
And we could connect that to this event.
And there's also another event we want to listen to inside of the marketplace service.
Or more exactly, it's called process receipt.
And this is actually a function that we need to supply to this, uh, property because this is a callback
property.
So any time anybody in our game purchases a developer product, this process receipt function is going
to be called.
And we need to handle any products that get purchased in our game.
We have to have full control of that.
And we have the full responsibility of processing and developer products.
So we could also create another function in here.
And we could call it process receipt.
And this is the function that's going to be processing every single purchase that is made inside of
our game.
Now inside of our on game comms event function, we're going to get the player and the action that this
player wants us to do, and we want to verify that this action is equal to our game comms enum dot two
server dot request respawn.
If it is, then what we could do is we could use our marketplace service and prompt a product purchase
to this player.
We're going to pass the player instance, and the ID or the product we wish to prompt to them is going
to be in our product ID enum.
And that's going to be our respawn product.
Now some things we want to verify.
First of all is we want to make sure that they haven't spam clicked this, uh, remote event or they
aren't spamming this remote event.
So we can basically, uh, set inside of the prompt cooldowns for this particular player equal to the
current tick.
So if this player does not have a key inside of our prompt cooldowns table, then we create one for
them right here.
Otherwise, what we could do is we could check if the current tick subtracted by when they last fired
this event.
Is less than our prompt cooldown, so that means they're firing this event way too often.
If that's the case, then we're just going to return.
Otherwise.
Another thing we need to make sure of is that this player is actually on the dead team.
So if this player team is not equal to teams dead, then obviously we can't, you know, respawn them,
they're already on the map, so there's no point to prompt them this purchase.
And another thing we want to verify is if the number of people on the alive team get players, we want
to make sure that is greater than zero.
If it's equal to zero, then that means all the players in our game have died and the game is over.
So we don't want any players to be able to purchase this respawn product because the game is done,
it's over.
So we're just going to return.
Otherwise, we prompt them to purchase this respawn product and if they do purchase it, that's when
our process receipt function gets called.
So inside of this process receipt function, we get passed something called a receipt info.
And this receipt info contains several information.
It first contains who exactly purchased this product.
And it also provides to us the ID of the product that was purchased.
So for example, we can get the player that purchased this product using the function and the player
service, get player by user ID, and we're going to pass inside of this receipt info.
There's a key called player ID.
And we can try to get the player instance who purchased this.
If this player for some reason is not in our game, let's say they left the game as soon as they purchased
this developer product.
Well, we don't want to do anything at all.
And this function has to return an enum of product purchase decision to let our game know what exactly
we're going to do when this process receipt function gets called, and if our player is not in the game,
then we don't want to charge them for this developer product.
So what we're going to do is we're going to return the enum dot product purchase decision dot not processed
yet.
So we're not going to process this order and we're not going to charge them because they left the game
while they tried to purchase it.
Otherwise.
If everything works out, then we can execute some functionality based on the ID of the product that
was purchased.
So what we can do is we can create a table up here.
And I'm going to call this product functions.
And inside of this table, we can create a whole bunch of different functions based on the ID of the
developer product as the key.
So inside of the product functions table, the key we could pass here is going to be our product id
enum dot respawn.
And we can set this equal to a lambda function.
And we would have this function get past the player.
And from this point what we would do is we would respawn the player because they purchased our respawn
product.
So inside of our process receipt function, after we verify that the player is in the game, we can
refer to our product functions table and pass the receipt info.
And get the product ID that was purchased.
And then we can call this function and pass the player that purchased the product.
And after all that functionality is completed for this particular developer product, then we can go
ahead and return the enum dot product purchase decision dot purchase granted.
So we charge them.
Everything went great and the server handled all of the functionality for this particular developer
product.
So what do we want to do when we want to respawn our player?
Well, first of all we need to figure out which respawn point to respawn them at.
So that means we're going to create a variable.
I'm going to call this selected respawn point, and I'm just going to set this to null for now.
And then we also need a variable I'm going to call it last distance.
And I'll just set it to some randomly high number like 10,000.
And what we need to do is we need to loop through every single respawn point inside of our respawn points
and basement table.
And what we need to do is calculate the distance from our I, Squidward to this point.
So we get this respawn point.
We get the position.
And we subtract that by the I Squidward humanoid root part and get that position and get the total magnitude
between these two points.
If this distance we just calculated is greater than our last distance.
So actually we need to set this value to zero and not 10,000 because we're calculating which point is
farthest away and not which point is closest.
So if this distance is greater than the last distance, then we can set last distance equal to this
distance we just calculated and set the selected respawn point equal to this respawn point.
After we loop through all of the different respawn points, and we've gone through the process of elimination
and figured out which respawn point is the farthest away from our eye.
And what we're going to do is we're going to check if our player has a character.
If for some reason our player does not have a character, then we're going to load this player's character.
So we use the low character function, and then we're going to set the player's team equal to the alive
team.
And we're going to set this player character humanoid route part dot C frame.
We're going to set that equal to the selected respawn point dot C frame.
So now they're inside of the map.
And the last thing we need to do is that since our player is not going to have any tools, we need to
go ahead and give them some.
So we're going to clone our flashlight tool.
We can just call this flashlight clone and that's in server storage dot tools dot flashlight.
We're going to clone that.
And we're also going to give them a glow stick.
So glow stick clone is in server storage dot tools dot glow stick.
And we're going to clone that as well.
And then we can set the flashlight clone dot parent equal to this player's backpack.
And let me denote this as a player here real quick.
And then for the same thing with our glow stick, we're going to set the parent equal to the player's
backpack.
And after we do all of that, then we can go ahead and notify this player that they've been successfully
respawned.
So again, if you remember in our game comms event, we can fire to this particular player here and
give them the action in our game comms enum dot two client that their respawn were granted and because
their respawn was granted, that means our player needs to disable the night vision that they had when
they were spectating, and they also need to disable their spectating frame and reset their camera.
So back inside of our main guy handler, what we can do is we can go ahead and listen to the game comms
event in there and listen to the on client event and connect a function to this and get the action and
the arguments supplied from the server.
And we can go ahead and check if this action is equal to the game comms enum dot two client dot respawn.
Granted, if it is, then we need to set the spectate frames visibility equal to false, and then we
need to use our manipulate camera Bindable and fire and give the action dot two client of toggle Night
Vision.
We want to turn our night vision off, so we need to set the set on variable equal to false.
And then we also want to use this event as well to go ahead and reset our camera back to the default.
So we're going to give them the action two client dot reset camera.
And I think that's all we need to do for this event.
So now any time our player clicks that respawn button, we're going to request to the server to respawn.
The server is going to ensure that everything checks out and then prompts us a purchase.
And if we purchase that product, then it's going to process the receipt.
It's going to execute the functionality for that particular product and everything should be good to
go.
So now we should be able to test whether or not our developer product is actually working.
So let's go ahead and test out with a three player server and I'll meet you there.
Alrighty.
So one of my players has died and they're currently spectating our two other players, and now we can
test whether or not our respawn button works.
So if I hit this there we go.
We get prompted to purchase the respawn.
And the great thing about testing in studio is that this is a test purchase and we will not be charged.
So this is just an example purchase.
But if I purchase this, hopefully I should get respawned into the map, so I'm going to buy it.
And there we go.
Your purchase of respawn succeeded and we hit okay.
And guess what?
Now we are back inside of the map with our tools and everything has been reset and we're back inside
of our basement.
Beautiful.
Now that means we can purchase this product multiple times.
So if I go and die again, let me just have myself die.
Let me go try to find where Squidward is at.
He sounds like he's in here.
There we go.
And I have died again and I'm back spectating these players.
But thankfully, if I just spend more money and I hit the respawn button and I buy it again, there
we go.
And we have now successfully respawned back into our game once more to try and escape our basement.
Beautiful.
So our developer product system is working great and you can easily add more developer products if you
wish in the future, and you're able to handle them all directly from our developer product service
module script.